from django.db import models

# Create your models here.

def validator_for_range(data_type, min_value, max_value):
    from django.core import validators
    def validator(field_data, all_data):
        value = data_type(field_data) # By now we assume that this works
        if value < min_value or value > max_value:
            raise validators.ValidationError(
                _("The value must be between %s and %s") %
                (min_value, max_value))
    return validator

class Resource(models.Model):
    code_name = models.CharField(maxlength=50)
    long_name = models.CharField(maxlength=50)
    daily_max = models.PositiveIntegerField(null=True)
    weekly_max = models.PositiveIntegerField(null=True)
    monthly_max = models.PositiveIntegerField(null=True)
    def __str__(self):
        return self.long_name
    class Admin:
        pass

class ResourceVacation(models.Model):
    "A vacation of a resource"
    resource = models.ForeignKey(Resource, edit_inline=models.STACKED,
                                 num_in_admin=1)
    start = models.DateField(core=True)
    end = models.DateField(core=True)
    def __str__(self):
        return "%s is on vacation from %s to %s" % (self.resource,
                                                    self.start, self.end)

class Task(models.Model):
    "A Task which is part of a project"
    code_name = models.CharField(maxlength=50)
    long_name = models.CharField(maxlength=50)
    priority = models.PositiveIntegerField(
        null=True,
        validator_list=[validator_for_range(int, 0, 1000)]
        )
    effort_in_hours = models.PositiveIntegerField(null=True)
    parent_task = models.ForeignKey('self', null=True)
    dependencies = models.ManyToManyField('self', symmetrical=False,
                                          filter_interface=models.HORIZONTAL,
                                          related_name='references')
    def __str__(self):
        return self.long_name
    class Admin:
        pass

class Allocation(models.Model):
    "An allocation of a resource to a task"
    task = models.ForeignKey(Task, edit_inline=models.STACKED, num_in_admin=1)
    resource = models.ForeignKey(Resource, related_name="allocations", core=True)
    alternative_resources = models.ManyToManyField(
        Resource, related_name="alternative_allocations",core=True,
        filter_interface=models.HORIZONTAL)
    persistent = models.BooleanField(default=False)
    mandatory = models.BooleanField(default=False)
    daily_max = models.PositiveIntegerField(null=True)
    weekly_max = models.PositiveIntegerField(null=True)
    monthly_max = models.PositiveIntegerField(null=True)
    def __str__(self):
        return "Allocation of %s on task %s" % (self.resource, self.task)

class Milestone(models.Model):
    "A project milestone"
    date = models.DateField()
    task = models.ForeignKey(Task)
    def __str__(self):
        return self.task.long_name
    class Admin:
        pass

class Project(models.Model):
    """
    A project to be planned.

    Conceptually it is simply a big task (represented by the root_task field.
    """
    start_date = models.DateField()
    root_task = models.ForeignKey(Task)
    
    def __str__(self):
        return self.root_task.long_name
    class Admin:
        pass

    
